package yxy.game.pm2.module.hero;

import yxy.cherry.battle.module.Position;
import yxy.game.pm2.Result;
import yxy.game.pm2.bean.Format;
import yxy.game.pm2.bean.Format.FormatType;
import yxy.game.pm2.bean.Hero;
import yxy.game.pm2.message.CampTowerMessage;
import yxy.game.pm2.message.FormatMessage;
import yxy.game.pm2.module.niubee.NiuBeeModule;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class FormatHandle {

    public Format get(String playerCode, FormatType type) {
        Format format = Format.get(playerCode, type);
        if (format == null) {
            format = new Format();
            Collection<Hero> heros = Hero.all(playerCode).values();
            for (Hero hero : heros) {
                format.setFm(hero.getCode());
                break;
            }
            Format.set(playerCode, type, format);
        }
        return format;
    }

    public Map<Position, String> formatCodes(String playerCode, Format format) {
        HashMap<Position, String> map = new HashMap<>();
        if (format.getFu() != null) {
            if (Hero.get(playerCode, format.getFu()) != null) {
                map.put(Position.FU, format.getFu());
            }
        }
        if (format.getFm() != null) {
            if (Hero.get(playerCode, format.getFm()) != null) {
                map.put(Position.FM, format.getFm());
            }
        }
        if (format.getFd() != null) {
            if (Hero.get(playerCode, format.getFd()) != null) {
                map.put(Position.FD, format.getFd());
            }
        }
        if (format.getBu() != null) {
            if (Hero.get(playerCode, format.getBu()) != null) {
                map.put(Position.BU, format.getBu());
            }
        }
        if (format.getBm() != null) {
            if (Hero.get(playerCode, format.getBm()) != null) {
                map.put(Position.BM, format.getBm());
            }
        }
        if (format.getBd() != null) {
            if (Hero.get(playerCode, format.getBd()) != null) {
                map.put(Position.BD, format.getBd());
            }
        }
        return map;
    }


    public ArrayList<String> formatCodesList(String playerCode, Format format) {
        ArrayList<String> list = new ArrayList<>();
        if (format.getFu() != null) {
            if (Hero.get(playerCode, format.getFu()) != null) {
                list.add(format.getFu());
            }
        }
        if (format.getFm() != null) {
            if (Hero.get(playerCode, format.getFm()) != null) {
                list.add(format.getFm());
            }
        }
        if (format.getFd() != null) {
            if (Hero.get(playerCode, format.getFd()) != null) {
                list.add(format.getFd());
            }
        }
        if (format.getBu() != null) {
            if (Hero.get(playerCode, format.getBu()) != null) {
                list.add(format.getBu());
            }
        }
        if (format.getBm() != null) {
            if (Hero.get(playerCode, format.getBm()) != null) {
                list.add(format.getBm());
            }
        }
        if (format.getBd() != null) {
            if (Hero.get(playerCode, format.getBd()) != null) {
                list.add(format.getBd());
            }
        }
        return list;
    }

    public Map<Position, Hero> formatHeros(String playerCode, FormatType type) {
        Format format = get(playerCode, type);
        return formatHeros(playerCode, format);
    }

    public Map<Position, Hero> formatHeros(String playerCode, Format format) {
        HashMap<Position, Hero> map = new HashMap<>();
        if (format.getFu() != null) {
            Hero herofu = Hero.get(playerCode, format.getFu());
            if (herofu != null) {
                map.put(Position.FU, herofu);
            }
        }
        if (format.getFm() != null) {
            Hero herofm = Hero.get(playerCode, format.getFm());
            if (herofm != null) {
                map.put(Position.FM, herofm);
            }
        }
        if (format.getFd() != null) {
            Hero herofd = Hero.get(playerCode, format.getFd());
            if (herofd != null) {
                map.put(Position.FD, herofd);
            }
        }
        if (format.getBu() != null) {
            Hero herobu = Hero.get(playerCode, format.getBu());
            if (herobu != null) {
                map.put(Position.BU, herobu);
            }
        }
        if (format.getBm() != null) {
            Hero herobm = Hero.get(playerCode, format.getBm());
            if (herobm != null) {
                map.put(Position.BM, herobm);
            }
        }
        if (format.getBd() != null) {
            Hero herobd = Hero.get(playerCode, format.getBd());
            if (herobd != null) {
                map.put(Position.BD, herobd);
            }
        }
        return map;
    }

//	public Collection<Hero> formatHeros(String playerCode, FormatType type) {
//		Format format = get(playerCode, type);
//		ArrayList<Hero> heros = new ArrayList<>();
//		if (format.getFu() != null) {
//			Hero hero = Hero.get(playerCode, format.getFu());
//			if (hero != null) {
//				heros.add(hero);
//			}
//		}
//		if (format.getFm() != null) {
//			Hero hero = Hero.get(playerCode, format.getFm());
//			if (hero != null) {
//				heros.add(hero);
//			}
//		}
//		if (format.getFd() != null) {
//			Hero hero = Hero.get(playerCode, format.getFd());
//			if (hero != null) {
//				heros.add(hero);
//			}
//		}
//		if (format.getBu() != null) {
//			Hero hero = Hero.get(playerCode, format.getBu());
//			if (hero != null) {
//				heros.add(hero);
//			}
//		}
//		if (format.getBm() != null) {
//			Hero hero = Hero.get(playerCode, format.getBm());
//			if (hero != null) {
//				heros.add(hero);
//			}
//		}
//		if (format.getBd() != null) {
//			Hero hero = Hero.get(playerCode, format.getBd());
//			if (hero != null) {
//				heros.add(hero);
//			}
//		}
//		return heros;
//	}

    public FormatMessage.Format get(Format format) {
        FormatMessage.Format.Builder formatBuilder = FormatMessage.Format.newBuilder();
        if (format.getFu() != null) {
            formatBuilder.setFU(format.getFu());
        }
        if (format.getFm() != null) {
            formatBuilder.setFM(format.getFm());
        }
        if (format.getFd() != null) {
            formatBuilder.setFD(format.getFd());
        }
        if (format.getBu() != null) {
            formatBuilder.setBU(format.getBu());
        }
        if (format.getBm() != null) {
            formatBuilder.setBM(format.getBm());
        }
        if (format.getBd() != null) {
            formatBuilder.setBD(format.getBd());
        }
        formatBuilder.setNB(format.getNb());
        return formatBuilder.build();
    }

    public Result check(String playerCode, Format format, ArrayList<Hero> hero) {
        Map<Integer, Hero> map = new HashMap<>();
        try {
            checkFormat(playerCode, format.getFu(), map);
            checkFormat(playerCode, format.getFm(), map);
            checkFormat(playerCode, format.getFd(), map);
            checkFormat(playerCode, format.getBu(), map);
            checkFormat(playerCode, format.getBm(), map);
            checkFormat(playerCode, format.getBd(), map);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.FormatSameHero;// 不能上阵同样的武将
        }

        // 检查神器
        if (format.getNb() > 0) {
            NiuBeeModule niubeeModule = NiuBeeModule.get(playerCode);
            if (niubeeModule.getProgress() < format.getNb()) {
                return Result.FormatNiubeeError;// 神器设置错误
            }
        }

        hero.addAll(map.values());

        return Result.Success;
    }


    public Result check(String playerCode, Format format) {
        Map<Integer, Hero> map = new HashMap<>();
        try {
            checkFormat(playerCode, format.getFu(), map);
            checkFormat(playerCode, format.getFm(), map);
            checkFormat(playerCode, format.getFd(), map);
            checkFormat(playerCode, format.getBu(), map);
            checkFormat(playerCode, format.getBm(), map);
            checkFormat(playerCode, format.getBd(), map);
        } catch (Exception e) {
            return Result.FormatSameHero;// 不能上阵同样的武将
        }
        return Result.Success;
    }


    //
    public void checkFormat(String playerCode, String code, Map<Integer, Hero> map) throws Exception {
        if (code == null) {
            return;
        }
        Hero hero = Hero.get(playerCode, code);
        int dataId = hero.getDataId();
        if (map.containsKey(dataId)) {
            throw new Exception();
        }
        // 武将id除去后两位后相同的为同一武将
        for (Hero h : map.values()) {
            if (h.getDataId() / 100 == hero.getDataId() / 100) {
                throw new Exception();
            }
        }
        map.put(dataId, hero);
    }

    // 使用all的方式，有性能问题
    public void checkFormat(String code, Map<String, Hero> all, Map<Integer, Hero> map) throws Exception {
        if (code == null) {
            return;
        }
        Hero hero = all.get(code);
        int dataId = hero.getDataId();
        if (map.containsKey(dataId)) {
            throw new Exception();
        }
        // 武将id除去后两位后相同的为同一武将
        for (Hero h : map.values()) {
            if (h.getDataId() / 100 == hero.getDataId() / 100) {
                throw new Exception();
            }
        }
        map.put(dataId, hero);
    }

    public boolean heroInFormat(String playerCode, String heroCode) {
        Format format = get(playerCode, FormatType.普通);
        if (format.getFu() != null && format.getFu().equals(heroCode)) {
            return true;
        }
        if (format.getFm() != null && format.getFm().equals(heroCode)) {
            return true;
        }
        if (format.getFd() != null && format.getFd().equals(heroCode)) {
            return true;
        }
        if (format.getBu() != null && format.getBu().equals(heroCode)) {
            return true;
        }
        if (format.getBm() != null && format.getBm().equals(heroCode)) {
            return true;
        }
        if (format.getBd() != null && format.getBd().equals(heroCode)) {
            return true;
        }
        return false;
    }

    /**
     * 获取阵营塔布阵阵容
     */
    public CampTowerMessage.Lineup getCampTowerFormat(Format format) {
        CampTowerMessage.Lineup.Builder formatBuilder = CampTowerMessage.Lineup.newBuilder();
        if (format.getFu() != null) {
            formatBuilder.setFU(format.getFu());
        }
        if (format.getFm() != null) {
            formatBuilder.setFM(format.getFm());
        }
        if (format.getFd() != null) {
            formatBuilder.setFD(format.getFd());
        }
        if (format.getBu() != null) {
            formatBuilder.setBU(format.getBu());
        }
        if (format.getBm() != null) {
            formatBuilder.setBM(format.getBm());
        }
        if (format.getBd() != null) {
            formatBuilder.setBD(format.getBd());
        }
        formatBuilder.setNB(format.getNb());
        return formatBuilder.build();
    }

}
